package com.captainbank.tcl.tclapplication.ui.activity.function;

import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.captainbank.tcl.tclapplication.R;
import com.captainbank.tcl.tclapplication.model.School;
import com.captainbank.tcl.tclapplication.model.Student;
import com.captainbank.tcl.tclapplication.ui.activity.basic.BaseActivity;
import com.captainbank.tcl.tclapplication.utils.MyToast;
import com.captainbank.tcl.tclapplication.utils.StringUtil;
import com.google.gson.Gson;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

import butterknife.BindView;
import butterknife.OnClick;
import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Function;
import io.reactivex.functions.Predicate;

/**
 * Created by TCL on 2019/4/19.
 * Describe:
 */
public class RxJava2Activity extends BaseActivity {
    @BindView(R.id.toolbar)
    Toolbar toolbar;
    @BindView(R.id.et_input)
    EditText etInput;
    @BindView(R.id.btn_clear)
    Button btnClear;
    @BindView(R.id.tv_show)
    TextView tvShow;

    private List<School> schoolsList;
    private List<Student> studentList;
    private DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    protected int getLayoutId() {
        return R.layout.activity_rxjava2;
    }

    @Override
    protected void initData() {
        schoolsList = new ArrayList<>();
        studentList = new ArrayList<>();
        studentList.add(new Student("张三", "男", 15));
        studentList.add(new Student("李四", "女", 13));
    }

    @Override
    protected void initView() {
        toolbar.setTitle(getString(R.string.title_rxjava2));

        btnClear.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                tvShow.setText("");
                return true;
            }
        });
    }

    @OnClick({R.id.btn_add, R.id.btn_clear, R.id.just, R.id.from, R.id.defer, R.id.interval, R.id.range, R.id.timer, R.id.repeat,
            R.id.concat, R.id.window, R.id.map, R.id.flatMap, R.id.buffer, R.id.take, R.id.distinct, R.id.filter, R.id.more})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.btn_add:
                String sName = etInput.getText().toString().trim();
                if (StringUtil.checkIsNotNull(sName)) {
                    schoolsList.add(new School(sName, studentList));
                    showSchoolData(schoolsList);
                } else {
                    MyToast.toastError(this, getString(R.string.hint_school), false);
                }
                break;

            case R.id.btn_clear:
                if (schoolsList.size() > 0) {
                    schoolsList.clear();
                    showSchoolData(schoolsList);
                } else {
                    MyToast.toastError(this, "早已清空！", false);
                }
                break;

            case R.id.just:
                Observable justObservable = Observable.just(studentList.get(0).getName(), studentList.get(1).getName());
                justObservable.subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                    }

                    @Override
                    public void onNext(String s) {
                        String str = tvShow.getText().toString();
                        if (StringUtil.checkIsNotNull(str)) {
                            StringBuilder sb = new StringBuilder(str);
                            tvShow.setText(sb.append("\n" + s));
                        } else {
                            tvShow.setText(s);
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                    }

                    @Override
                    public void onComplete() {
                    }
                });
                break;

            case R.id.from:
                if (schoolsList.size() > 0) {
                    Observable formObservable = Observable.fromIterable(schoolsList);
                    formObservable.subscribe(new Observer<School>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                        }

                        @Override
                        public void onNext(School s) {
                            String str = tvShow.getText().toString();
                            if (StringUtil.checkIsNotNull(str)) {
                                StringBuilder sb = new StringBuilder(str);
                                tvShow.setText(sb.append("\n" + s.getName()));
                            } else {
                                tvShow.setText(s.getName());
                            }
                        }

                        @Override
                        public void onError(Throwable e) {
                        }

                        @Override
                        public void onComplete() {
                        }
                    });
                } else {
                    MyToast.toastError(this, "请先添加数据", false);
                }
                break;

            case R.id.defer:
                final String sdefer = etInput.getText().toString().trim();
                if (StringUtil.checkIsNotNull(sdefer)) {
                    Observable deferObservable = Observable.defer(new Callable<Observable<String>>() {
                        @Override
                        //注意此处的call方法没有Subscriber参数
                        public Observable<String> call() {
                            return Observable.just(sdefer);
                        }
                    });
                    deferObservable.subscribe(new Observer<String>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                        }

                        @Override
                        public void onNext(String s) {
                            tvShow.setText(s);
                        }

                        @Override
                        public void onError(Throwable e) {
                        }

                        @Override
                        public void onComplete() {
                        }
                    });
                } else {
                    MyToast.toastError(this, "请输入", false);
                }
                break;

            case R.id.interval:

                Observable intervalObservable = Observable
                        .interval(5, TimeUnit.SECONDS)//每隔X秒发送一次
                        .take(10)
                        .observeOn(AndroidSchedulers.mainThread());
                intervalObservable.subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                    }

                    @Override
                    public void onNext(Long o) {
                        String str = tvShow.getText().toString();
                        if (StringUtil.checkIsNotNull(str)) {
                            StringBuilder sb = new StringBuilder(str);
                            tvShow.setText(sb.append("\n" + "当前时间：" + df.format(new Date())));
                        } else {
                            tvShow.setText("当前时间：" + df.format(new Date()));
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                    }

                    @Override
                    public void onComplete() {
                        String str = tvShow.getText().toString();
                        if (StringUtil.checkIsNotNull(str)) {
                            StringBuilder sb = new StringBuilder(str);
                            tvShow.setText(sb.append("\n" + "运行结束"));
                        }
                    }
                });
                break;

            case R.id.range:
                String inputNumStr = etInput.getText().toString().trim();
                if (!StringUtil.checkIsNotNull(inputNumStr)) {
                    MyToast.toastError(this, "请输入起始数字", false);
                    return;
                } else {
                    try {
                        Integer.parseInt(inputNumStr);
                    } catch (Exception e) {
                        MyToast.toastError(this, "请输入纯数字", false);
                        e.printStackTrace();
                        return;
                    }
                }
                int inputNum = Integer.parseInt(inputNumStr);
                Observable rangeObservable = Observable
                        .range(inputNum, 10)//（起始数字，输出个数（逐步+1输出））
                        .observeOn(AndroidSchedulers.mainThread());
                //将发送整数10，11，12，13，14
                rangeObservable.subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                    }

                    @Override
                    public void onNext(Integer s) {
                        String str = tvShow.getText().toString();
                        if (StringUtil.checkIsNotNull(str)) {
                            StringBuilder sb = new StringBuilder(str);
                            tvShow.setText(sb.append("\n" + "发送：" + s));
                        } else {
                            tvShow.setText("运行开始\n发送：" + s);
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                    }

                    @Override
                    public void onComplete() {
                        String str = tvShow.getText().toString();
                        if (StringUtil.checkIsNotNull(str)) {
                            StringBuilder sb = new StringBuilder(str);
                            tvShow.setText(sb.append("\n" + "运行结束"));
                        }
                    }
                });
                break;

            case R.id.timer:
                final String sTimer = etInput.getText().toString().trim();
                if (StringUtil.checkIsNotNull(sTimer)) {
                    Observable timeObservable = Observable
                            .timer(3, TimeUnit.SECONDS)//3秒后发射一个值
                            .observeOn(AndroidSchedulers.mainThread());
                    timeObservable.subscribe(new Observer<Long>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                        }

                        @Override
                        public void onNext(Long s) {
                            tvShow.setText(sTimer);
                        }

                        @Override
                        public void onError(Throwable e) {
                        }

                        @Override
                        public void onComplete() {
                        }
                    });
                } else {
                    MyToast.toastError(this, "请输入", false);
                }

                break;

            case R.id.repeat:
                String sRepeat = etInput.getText().toString().trim();
                if (StringUtil.checkIsNotNull(sRepeat)) {
                    Observable repeatObservable = Observable
                            .just(sRepeat).repeat(3)//重复发射3次
                            .observeOn(AndroidSchedulers.mainThread());
                    repeatObservable.subscribe(new Observer<String>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                        }

                        @Override
                        public void onNext(String s) {
                            String str = tvShow.getText().toString();
                            if (StringUtil.checkIsNotNull(str)) {
                                StringBuilder sb = new StringBuilder(str);
                                tvShow.setText(sb.append("\n" + "发送：" + s));
                            } else {
                                tvShow.setText("运行开始\n发送：" + s);
                            }
                        }

                        @Override
                        public void onError(Throwable e) {
                        }

                        @Override
                        public void onComplete() {
                            String str = tvShow.getText().toString();
                            if (StringUtil.checkIsNotNull(str)) {
                                StringBuilder sb = new StringBuilder(str);
                                tvShow.setText(sb.append("\n" + "运行结束"));
                            }
                        }
                    });
                } else {
                    MyToast.toastError(this, "请输入", false);
                }
                break;

            case R.id.concat:
                final String[] aStrings = {"A1", "A2", "A3", "A4"};
                final String[] bStrings = {"B1", "B2", "B3"};
                final Observable<String> aObservable = Observable.fromArray(aStrings);
                final Observable<String> bObservable = Observable.fromArray(bStrings);
                Observable concatObservable = Observable.concat(aObservable, bObservable);
                concatObservable.subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                    }

                    @Override
                    public void onNext(String s) {
                        String str = tvShow.getText().toString();
                        if (StringUtil.checkIsNotNull(str)) {
                            StringBuilder sb = new StringBuilder(str);
                            tvShow.setText(sb.append("\n" + "发送：" + s));
                        } else {
                            tvShow.setText("运行开始\n发送：" + s);
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                    }

                    @Override
                    public void onComplete() {
                        String str = tvShow.getText().toString();
                        if (StringUtil.checkIsNotNull(str)) {
                            StringBuilder sb = new StringBuilder(str);
                            tvShow.setText(sb.append("\n" + "运行结束"));
                        }
                    }
                });
                break;

            case R.id.window:
                Observable windowObservable = Observable
                        .interval(1, TimeUnit.SECONDS)
                        .take(15)
                        .window(5, TimeUnit.SECONDS)//5秒后，发射前五秒所发射的数据
                        .observeOn(AndroidSchedulers.mainThread());
                windowObservable.subscribe(new Observer<Object>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                    }

                    @Override
                    public void onNext(Object o) {
                        String str = tvShow.getText().toString();
                        if (StringUtil.checkIsNotNull(str)) {
                            StringBuilder sb = new StringBuilder(str);
                            tvShow.setText(sb.append("\n" + "当前时间：" + df.format(new Date())));
                        } else {
                            tvShow.setText("运行开始：\n" + df.format(new Date()));
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                    }

                    @Override
                    public void onComplete() {
                        String str = tvShow.getText().toString();
                        if (StringUtil.checkIsNotNull(str)) {
                            StringBuilder sb = new StringBuilder(str);
                            tvShow.setText(sb.append("\n" + "运行结束"));
                        }
                    }
                });
                break;

            case R.id.map:
                if(schoolsList.size()>0){
                    Observable mapObservable = Observable.fromIterable(schoolsList).map(new Function<School,String>() {
                        @Override
                        public String apply(School o) throws Exception {
                            return "校名：" + o.getName();
                        }
                    });
                    mapObservable.subscribe(new Observer<String>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                        }

                        @Override
                        public void onNext(String s) {
                            String str = tvShow.getText().toString();
                            if (StringUtil.checkIsNotNull(str)) {
                                StringBuilder sb = new StringBuilder(str);
                                tvShow.setText(sb.append("\n" + s));
                            } else {
                                tvShow.setText("运行开始：\n" + s);
                            }
                        }

                        @Override
                        public void onError(Throwable e) {
                        }

                        @Override
                        public void onComplete() {
                            String str = tvShow.getText().toString();
                            if (StringUtil.checkIsNotNull(str)) {
                                StringBuilder sb = new StringBuilder(str);
                                tvShow.setText(sb.append("\n" + "运行结束"));
                            }
                        }
                    });
                }else{
                    MyToast.toastError(this,"请添加数据",false);
                }
                break;

            case R.id.flatMap:
                if(schoolsList.size()>0){
                    Observable flatmapObservable = Observable.fromIterable(schoolsList).flatMap(new Function<School,Observable<Student>>() {
                        @Override
                        public Observable<Student> apply(School school) throws Exception {
                            return Observable.fromIterable(school.getStudents());
                        }
                    });
                    flatmapObservable.subscribe(new Observer<Student>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                        }

                        @Override
                        public void onNext(Student s) {
                            String str = tvShow.getText().toString();
                            if (StringUtil.checkIsNotNull(str)) {
                                StringBuilder sb = new StringBuilder(str);
                                tvShow.setText(sb.append("\n" + s.getName()));
                            } else {
                                tvShow.setText("运行开始：\n" + s.getName());
                            }
                        }

                        @Override
                        public void onError(Throwable e) {
                        }

                        @Override
                        public void onComplete() {
                            String str = tvShow.getText().toString();
                            if (StringUtil.checkIsNotNull(str)) {
                                StringBuilder sb = new StringBuilder(str);
                                tvShow.setText(sb.append("\n" + "运行结束"));
                            }
                        }
                    });
                }else{
                    MyToast.toastError(this,"请添加数据",false);
                }
                break;

            case R.id.buffer:
                if(schoolsList.size()>0){
                    Observable mapObservable = Observable.fromIterable(schoolsList).map(new Function<School,School>() {
                        @Override
                        public School apply(School school) throws Exception {
                            String sName = school.getName();
                            school.setName("修改校名：" + sName);
                            return school;
                        }
                    }).buffer(schoolsList.size());
                    mapObservable.subscribe(new Observer<List<School>>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                        }

                        @Override
                        public void onNext(List<School> list) {
                            String str = tvShow.getText().toString();
                            if (StringUtil.checkIsNotNull(str)) {
                                StringBuilder sb = new StringBuilder(str);
                                tvShow.setText(sb.append("\n" + new Gson().toJson(list)));
                            } else {
                                tvShow.setText("运行开始：\n" + new Gson().toJson(list));
                            }
                        }

                        @Override
                        public void onError(Throwable e) {
                        }

                        @Override
                        public void onComplete() {
                            String str = tvShow.getText().toString();
                            if (StringUtil.checkIsNotNull(str)) {
                                StringBuilder sb = new StringBuilder(str);
                                tvShow.setText(sb.append("\n" + "运行结束"));
                            }
                        }
                    });
                }else{
                    MyToast.toastError(this,"请添加数据",false);
                }
                break;

            case R.id.take:
                if(schoolsList.size()>0){
                    Observable mapObservable = Observable.fromIterable(schoolsList)
                            .take(1)
                            .map(new Function<School,School>() {
                        @Override
                        public School apply(School school) throws Exception {
                            String sName = school.getName();
                            school.setName("修改校名：" + sName);
                            return school;
                        }
                    }).buffer(schoolsList.size());
                    mapObservable.buffer(1).subscribe(new Observer<List<School>>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                        }

                        @Override
                        public void onNext(List<School> list) {
                            String str = tvShow.getText().toString();
                            if (StringUtil.checkIsNotNull(str)) {
                                StringBuilder sb = new StringBuilder(str);
                                tvShow.setText(sb.append("\n" + new Gson().toJson(list)));
                            } else {
                                tvShow.setText("运行开始：\n" + new Gson().toJson(list));
                            }
                        }

                        @Override
                        public void onError(Throwable e) {
                        }

                        @Override
                        public void onComplete() {
                            String str = tvShow.getText().toString();
                            if (StringUtil.checkIsNotNull(str)) {
                                StringBuilder sb = new StringBuilder(str);
                                tvShow.setText(sb.append("\n" + "运行结束"));
                            }
                        }
                    });
                }else{
                    MyToast.toastError(this,"请添加数据",false);
                }
                break;

            case R.id.distinct:
                Observable distinctObservable = Observable.just(1,2,3,3,1,4,5,5,6).distinct();
                distinctObservable.subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                    }

                    @Override
                    public void onNext(Integer s) {
                        String str = tvShow.getText().toString();
                        if (StringUtil.checkIsNotNull(str)) {
                            StringBuilder sb = new StringBuilder(str);
                            tvShow.setText(sb.append("\n" + s));
                        } else {
                            tvShow.setText("运行开始-->\n(1,2,3,3,1,4,5,5,6去重):\n" + s);
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                    }

                    @Override
                    public void onComplete() {
                        String str = tvShow.getText().toString();
                        if (StringUtil.checkIsNotNull(str)) {
                            StringBuilder sb = new StringBuilder(str);
                            tvShow.setText(sb.append("\n" + "运行结束"));
                        }
                    }
                });
                break;

            case R.id.filter:
                Observable filterObservable = Observable.just(1,2,3,3,1,4,5,5,6).filter(new Predicate<Integer>() {
                    @Override
                    public boolean test(Integer integer) throws Exception {
                        return integer % 2==0;//偶数
                    }
                });
                filterObservable.subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                    }

                    @Override
                    public void onNext(Integer s) {
                        String str = tvShow.getText().toString();
                        if (StringUtil.checkIsNotNull(str)) {
                            StringBuilder sb = new StringBuilder(str);
                            tvShow.setText(sb.append("\n" + s));
                        } else {
                            tvShow.setText("运行开始-->\n(1,2,3,3,1,4,5,5,6取偶数):\n" + s);
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                    }

                    @Override
                    public void onComplete() {
                        String str = tvShow.getText().toString();
                        if (StringUtil.checkIsNotNull(str)) {
                            StringBuilder sb = new StringBuilder(str);
                            tvShow.setText(sb.append("\n" + "运行结束"));
                        }
                    }
                });
                break;

            case R.id.more:
                MyToast.toastNormal(this, "更多");
                break;
        }
    }

    private void showSchoolData(List<School> schoolsList) {
        String showString = new Gson().toJson(schoolsList);
        tvShow.setText(showString);
    }
}
